home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / prefix / prefix.rab < prev   
Encoding:
Text File  |  1992-01-14  |  12.2 KB  |  460 lines

  1. /* 
  2.  * prefix.c --
  3.  *
  4.  *    Program to print and manipulate the prefix table.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/cmds/prefix/RCS/prefix.c,v 1.9 91/10/25 15:57:01 rab Exp Locker: rab $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <fs.h>
  21. #include <fsCmd.h>
  22. #include <host.h>
  23. #include <option.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <status.h>
  27. #include <sysStats.h>
  28. #include <sys/stat.h>
  29.  
  30. static int PrintPrefixEntry _ARGS_ ((Fs_Prefix *prefixPtr));
  31. static void validateLocalPath _ARGS_ ((char *path));
  32.  
  33. extern int errno;
  34. static char *programName;
  35.  
  36. /*
  37.  * Command line options.
  38.  */
  39.  
  40. static int print = 0;
  41. static int readOnly = 0;
  42. static int localAccess = 0;
  43. static int force = FALSE;
  44. static char *loadedPrefix = (char *) NULL;
  45. static char *deviceName = (char *) NULL;
  46. static char *unmountName = (char *) NULL;
  47. static char *exportedPrefix = (char *) NULL;
  48. static char *clearedPrefix = (char *) NULL;
  49. static char *deletedPrefix = (char *) NULL;
  50. static char *Prefix = (char *) NULL;
  51. static char *localPath = (char *) NULL;
  52. static char *addHostName = NULL;
  53. static char *delHostName = NULL;
  54. static char *serverName = NULL;
  55.  
  56. static Option optionArray[] = {
  57.     {OPT_TRUE,   "p", (char *) &print,
  58.     "Print the prefix table or export list"},
  59.     {OPT_TRUE,   "f", (char *) &force,
  60.     "Force the prefix, even if the path doesn't exist"},
  61.     {OPT_STRING, "a", (char *) &loadedPrefix,
  62.     "Next argument is prefix to add"},
  63.     {OPT_STRING,  "s", (char *) &serverName,
  64.     "Next argument is name or id of server for added prefix (use with -a)"},
  65.     {OPT_STRING, "l", (char *) &localPath,
  66.     "Next argument is directory to mount/export (with -x, -M or -U)"},
  67.     {OPT_STRING, "M", (char *) &deviceName,
  68.     "Next argument is device to mount (use -l too)"},
  69.     {OPT_TRUE,     "r", (char *) &readOnly,
  70.     "Mount read only"},
  71.     {OPT_TRUE,     "L", (char *) &localAccess,
  72.     "Mount locally only; do not export"},
  73.     {OPT_STRING, "U", (char *) &unmountName,
  74.     "Next argument is prefix to unmount"},
  75.     {OPT_STRING, "x", (char *) &exportedPrefix, 
  76.     "Next argument is exported prefix (use with -p, -l, or -[hH])"},
  77.     {OPT_STRING, "h", (char *) &addHostName,
  78.     "Next argument is name or id of host to add to export list"},
  79.     {OPT_STRING, "H", (char *) &delHostName,
  80.     "Next argument is name or id of host to delete from export list"},
  81.     {OPT_STRING, "c", (char *) &clearedPrefix,
  82.     "Next argument is prefix to clear handle for"},
  83.     {OPT_STRING, "d", (char *) &deletedPrefix, 
  84.     "Next argument is prefix to delete altogether"},
  85. };
  86.  
  87.  
  88.  
  89. /*
  90.  *----------------------------------------------------------------------
  91.  *
  92.  * main --
  93.  *
  94.  *    Collects arguments and uses Fs_Command to manipulate the
  95.  *    prefix table.
  96.  *
  97.  * Results:
  98.  *    None.
  99.  *
  100.  * Side effects:
  101.  *    Calls Fs_Command...
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105.  
  106. main(argc, argv)
  107.     int argc;
  108.     char *argv[];
  109. {
  110.     register     ReturnStatus status = SUCCESS;    /* status of system calls */
  111.     int     flags;
  112.     int     addHostID = -1;
  113.     int     delHostID = -1;
  114.     int     serverID = FS_NO_SERVER;
  115.     Host_Entry    *entry;
  116.     int        scanned;
  117.     int        temp;
  118.  
  119.     programName = argv[0];
  120.     if (argc == 1) {
  121.     print = 1;
  122.     } else {
  123.     argc = Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray),
  124.         OPT_ALLOW_CLUSTERING);
  125.     }
  126.  
  127.     if (argc != 1) {
  128.     fprintf(stderr, "%s got extraneous argument \"%s\".\n", argv[0],
  129.         argv[1]);
  130.     Opt_PrintUsage(argv[0], optionArray, Opt_Number(optionArray));
  131.     exit(1);
  132.     }
  133.     if (addHostName != (char *) NULL) {
  134.     scanned = sscanf(addHostName, " %d", &temp);
  135.     if (scanned == 1) {
  136.         addHostID = temp;
  137.     } else {
  138.         entry = Host_ByName(addHostName);
  139.         if (entry == NULL) {
  140.         fprintf(stderr, "No such host \"%s\"\n", addHostName);
  141.         exit(1);
  142.         }
  143.         addHostID = entry->id;
  144.     }
  145.     }
  146.     if (delHostName != (char *) NULL) {
  147.     scanned = sscanf(delHostName, " %d", &temp);
  148.     if (scanned == 1) {
  149.         delHostID = temp;
  150.     } else {
  151.         entry = Host_ByName(delHostName);
  152.         if (entry == NULL) {
  153.         fprintf(stderr, "No such host \"%s\"\n", delHostName);
  154.         exit(1);
  155.         }
  156.         delHostID = entry->id;
  157.     }
  158.     }
  159.     if (serverName != (char *) NULL) {
  160.     scanned = sscanf(serverName, " %d", &temp);
  161.     if (scanned == 1) {
  162.         serverID = temp;
  163.     } else {
  164.         entry = Host_ByName(serverName);
  165.         if (entry == NULL) {
  166.         fprintf(stderr, "No such host \"%s\"\n", serverName);
  167.         exit(1);
  168.         }
  169.         serverID = entry->id;
  170.     }
  171.     }
  172.     if (loadedPrefix != (char *) NULL) {
  173.     /*
  174.      * Load a prefix
  175.      *    Load a prefix into the prefix table.
  176.      *    A prefix in the prefix table causes an attempt to find the
  177.      *    server the first time a file is opened under that prefix.
  178.      *      If serverID == FS_NO_SERVER then a broadcast is done,
  179.      *    otherwise the server is contacted directly.
  180.      */
  181.     Fs_PrefixLoadInfo    loadInfo;
  182.  
  183.     (void) strcpy(loadInfo.prefix, loadedPrefix);
  184.     loadInfo.serverID = serverID;
  185.     status = Fs_Command(FS_PREFIX_LOAD, sizeof(Fs_PrefixLoadInfo), 
  186.          &loadInfo);
  187.     if (status != SUCCESS) {
  188.         fprintf(stderr, "%s couldn't load prefix: %s.\n",
  189.             argv[0], Stat_GetMsg(status));
  190.         exit(1);
  191.     }
  192.     }
  193.     if (deviceName != (char *)NULL) {
  194.     validateLocalPath(localPath);
  195.     flags = 0;
  196.     if (localAccess) {
  197.         flags |= FS_ATTACH_LOCAL;
  198.     }
  199.     if (readOnly) {
  200.         flags |= FS_ATTACH_READ_ONLY;
  201.     }
  202.     status = Fs_AttachDisk(deviceName, localPath, flags);
  203.     if (status != SUCCESS) {
  204.         fprintf(stderr, "Mount \"%s\" on \"%s\": %s\n", deviceName,
  205.             localPath, Stat_GetMsg(status));
  206.         exit(1);
  207.     }
  208.     localPath = (char *)NULL;
  209.     }
  210.     if (unmountName != (char *)NULL) {
  211.     status = Fs_AttachDisk(deviceName, unmountName, FS_DETACH);
  212.     if (status != SUCCESS) {
  213.         fprintf(stderr, "Unmount \"%s\": %s\n", unmountName,
  214.             Stat_GetMsg(status));
  215.         exit(1);
  216.     }
  217.     }
  218.     if (addHostID != -1 || delHostID != -1) {
  219.     Fs_PrefixControl    prefixControl;
  220.     /*
  221.      * Add or remove a host from a prefix's export list.
  222.      */
  223.     if (exportedPrefix == (char *) NULL) {
  224.         fprintf(stderr, "Specify an exported prefix with -x\n");
  225.         Opt_PrintUsage(argv[0], optionArray, Opt_Number(optionArray));
  226.         exit(1);
  227.     }
  228.     if (addHostID != -1) {
  229.         prefixControl.clientID = addHostID;
  230.         prefixControl.delete = FALSE;
  231.     } else {
  232.         prefixControl.clientID = delHostID;
  233.         prefixControl.delete = TRUE;
  234.     }
  235.     (void) strcpy(prefixControl.prefix, exportedPrefix);
  236.     status = Fs_Command(FS_PREFIX_CONTROL, sizeof(prefixControl),
  237.         &prefixControl);
  238.     if (status != SUCCESS) {
  239.         fprintf(stderr, "%s couldn't add/delete host: %s.\n",
  240.             argv[0], Stat_GetMsg(status));
  241.         exit(1);
  242.     }
  243.     exportedPrefix = (char *) NULL;
  244.     }
  245.     if (exportedPrefix != (char *) NULL) {
  246.     if (print) {
  247.         /*
  248.          * Print the export list of this prefix.
  249.          */
  250.         char buffer[100 * sizeof(int)];
  251.         int *exportList = (int *)buffer;
  252.         (void) strcpy(buffer, exportedPrefix);
  253.         status = Sys_Stats(SYS_FS_PREFIX_EXPORT, sizeof(buffer), buffer);
  254.         if (status != SUCCESS) {
  255.         fprintf(stderr, "%s: couldn't get export list\n",
  256.             exportedPrefix);
  257.         exit(status);
  258.         } else if (*exportList == 0) {
  259.         printf("%s exported to all hosts\n", exportedPrefix);
  260.         } else {
  261.         printf("\"%s\" EXPORT LIST\n", exportedPrefix);
  262.         for ( ; *exportList != 0 ; exportList++) {
  263.             Host_Entry *hostPtr;
  264.             hostPtr = Host_ByID(*exportList);
  265.             if (hostPtr == (Host_Entry *)NULL) {
  266.             break;
  267.             }
  268.             printf("\t<%d> %s\n", hostPtr->id, hostPtr->name);
  269.         }
  270.         }
  271.     } else {
  272.         Fs_TwoPaths args;
  273.  
  274.         validateLocalPath(localPath);
  275.  
  276.         /*
  277.          * Export a prefix.  This is used on a server to explicitly
  278.          * export a local directory under some prefix.
  279.          */
  280.     
  281.         args.pathLen1 = strlen(localPath) + 1;
  282.         args.path1 = localPath;
  283.         args.pathLen2 = strlen(exportedPrefix) + 1;
  284.         args.path2 = exportedPrefix;
  285.  
  286.         status = Fs_Command(FS_PREFIX_EXPORT, sizeof(Fs_TwoPaths), &args);
  287.         if (status != SUCCESS) {
  288.         fprintf(stderr, "%s couldn't export prefix: %s.\n",
  289.             argv[0], Stat_GetMsg(status));
  290.         exit(1);
  291.         }
  292.     }
  293.     }
  294.     if (clearedPrefix != (char *) NULL) {
  295.     /*
  296.      * Clear a prefix's file handle.
  297.      */
  298.     status = Fs_Command(FS_PREFIX_CLEAR, strlen(clearedPrefix) + 1,
  299.         clearedPrefix);
  300.     if (status != SUCCESS) {
  301.         fprintf(stderr, "%s couldn't clear prefix handle: %s.\n",
  302.             argv[0], Stat_GetMsg(status));
  303.         exit(1);
  304.     }
  305.     }
  306.     if (deletedPrefix != (char *) NULL) {
  307.     /*
  308.      * Delete a prefix
  309.      */
  310.     status = Fs_Command(FS_PREFIX_DELETE, strlen(deletedPrefix) + 1,
  311.         deletedPrefix);
  312.     if (status != SUCCESS) {
  313.         fprintf(stderr, "%s couldn't delete prefix: %s.\n",
  314.             argv[0], Stat_GetMsg(status));
  315.         exit(1);
  316.     }
  317.     }
  318.     if (print) {
  319.     register int index;
  320.     Fs_Prefix prefix;
  321.  
  322.     printf("%-20s %-8s %7s %7s %8s\n", 
  323.         "Prefix", "Server", "Domain", "File #", "Version");
  324.     for (index = 0 ; status == SUCCESS; index++) {
  325.         bzero((char *) &prefix, sizeof(Fs_Prefix));
  326.         status = Sys_Stats(SYS_FS_PREFIX_STATS, index, (Address) &prefix);
  327.         if (status == SUCCESS) {
  328.         PrintPrefixEntry(&prefix);
  329.         }
  330.     }
  331.     }
  332.     exit(0);
  333. }
  334.  
  335. /*
  336.  *----------------------------------------------------------------------
  337.  *
  338.  * PrintPrefixEntry --
  339.  *
  340.  *    Print out information for a single prefix table entry.
  341.  *
  342.  * Results:
  343.  *    None.
  344.  *
  345.  * Side effects:
  346.  *    Stuff gets printed.
  347.  *
  348.  *----------------------------------------------------------------------
  349.  */
  350.  
  351. static int 
  352. PrintPrefixEntry(prefixPtr)
  353.     Fs_Prefix *prefixPtr;
  354. {
  355.     static char serverName[9];
  356.     static int  prevServerID = -1;
  357.     Host_Entry  *host;
  358.  
  359.     printf("%-20s", prefixPtr->prefix);
  360.  
  361.     if (prefixPtr->serverID > 0) {
  362.  
  363.     /*
  364.      * If the server ID is the same as the previous entry's ID, then
  365.      * we can reuse serverName and save a call to Host_ByID.
  366.      */
  367.     if (prefixPtr->serverID == prevServerID) {
  368.         printf(" %-8s", serverName);
  369.     } else {
  370.         host = Host_ByID(prefixPtr->serverID);
  371.         if (host != (Host_Entry *)NULL) {
  372.         register int charCnt;
  373.         for (charCnt = 0 ; charCnt < sizeof(serverName) ; charCnt++) {
  374.             if (host->name[charCnt] == '.' ||
  375.             host->name[charCnt] == '\0') {
  376.             serverName[charCnt] = '\0';
  377.             break;
  378.             } else {
  379.             serverName[charCnt] = host->name[charCnt];
  380.             }
  381.         }
  382.         serverName[sizeof(serverName)-1] = '\0';
  383.         printf(" %-8s", serverName);
  384.         prevServerID = prefixPtr->serverID;
  385.         } else {
  386.         printf(" (%d)", prefixPtr->serverID);
  387.         }
  388.     }
  389.     } else {
  390.     printf(" %-8s", "(none)");
  391.     }
  392.  
  393.     printf(" %7d %7d %8d", prefixPtr->domain, prefixPtr->fileNumber, 
  394.         prefixPtr->version);
  395.  
  396.     if (prefixPtr->flags & FS_LOCAL_PREFIX) {
  397.     printf(" local   ");
  398.     }
  399.     if (prefixPtr->flags & FS_IMPORTED_PREFIX) {
  400.     printf(" imported");
  401.     }
  402.     if (prefixPtr->flags & FS_EXPORTED_PREFIX) {
  403.     printf(" exported");
  404.     }
  405.     printf("\n");
  406. }
  407.  
  408. /*
  409.  *----------------------------------------------------------------------
  410.  *
  411.  * validateLocalPath --
  412.  *
  413.  *    Make sure the local path specified with the -l option is valid.
  414.  *    It must be an absolute path starting with '/'.
  415.  *      It must be an already existing remote link.
  416.  *
  417.  * Results:
  418.  *    None.
  419.  *
  420.  * Side effects:
  421.  *    Will exit with an error code of 1 if the path is invalid.
  422.  *
  423.  *----------------------------------------------------------------------
  424.  */
  425.  
  426. static void
  427. validateLocalPath(path)
  428.     char *path;
  429. {
  430.     struct stat statBuf;
  431.  
  432.     if (force) {
  433.     /* Do not check the path if the force flag is set. */
  434.     return;
  435.     }
  436.     if (path == NULL) {
  437.     fprintf(stderr, "%s:  You must specify a local directory with -l\n",
  438.         programName);
  439.     Opt_PrintUsage(programName, optionArray, Opt_Number(optionArray));
  440.     exit(1);
  441.     } else if (*path != '/') {
  442.     fprintf(stderr,
  443.         "%s:  %s is not an absolute path.  It must start with '/'\n",
  444.         programName, path);
  445.     exit(1);
  446.     }
  447.     if (lstat(path, &statBuf) < 0) {
  448.     fprintf(stderr, "%s:  Cannot lstat %s:  %s\n",
  449.         programName, path, strerror(errno));
  450.     exit(1);
  451.     }
  452.     if ((statBuf.st_mode & S_IFMT) != S_IFRLNK) {
  453.     fprintf(stderr, "%s:  %s is not a remote link.\n",
  454.         programName, path);
  455.     exit(1);
  456.     }
  457.     return;
  458. }
  459.  
  460.